/*
 * 支付宝平台(JAVA) SDK
 * 工具类API
 * 1. 用户授权地址拼装
 * 2. 通过授权码换取换取授权访问令牌
 * 3. 支付宝会员授权信息查询接口
 */
package org.alipay4j.component.util;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import org.alipay4j.Alipay;
import org.alipay4j.AlipayException;
import org.alipay4j.Configuration;
import org.alipay4j.component.AbstractComponent;
import org.alipay4j.http.AlipayHttpsClient;
import org.alipay4j.http.Response;
import org.alipay4j.model.sns.SnsAccessToken;
import org.alipay4j.model.sns.SnsUser;
import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSONObject;

/**
 * @author 贺亮
 * 网页授权获取用户基本信息
 */
public class SnsComponent extends AbstractComponent {

	public SnsComponent(Alipay alipay) {
		super(alipay);
	}
	
	
	/**
	 * 拼接用户授权地址
	 * @return 授权URL地址
	 * @throws AlipayException
	 */
	public String getUserOAuthUrl(String scope,String state) throws AlipayException {
		if (StringUtils.isEmpty(alipay.getAppId())) {
            throw new IllegalArgumentException("appid can't be null or empty");
        }
		String url = "";
		//拼接URL
		@SuppressWarnings("deprecation")
		String param = "?app_id="+alipay.getAppId()+"&scope="+scope+"&state="+state+"&redirect_uri="+URLEncoder.encode(alipay.getAlipayConfig().getUserAuthUri());
		//判断是否为沙箱
		String gateway = alipay.getAlipayConfig().getAlipayGateway();
		if(gateway.indexOf("dev")!=-1) {
			url = "https://openauth.alipaydev.com/oauth2/publicAppAuthorize.htm";
		} else {
			url = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm";
		}
		return url+param;
	}
	
	/**
	 * 获取支付宝用户user_id
	 * @param code 授权码
	 * @return 支付宝用户user_id
	 * @throws AlipayException
	 */
	public String getUserId(String code) throws AlipayException{
		SnsAccessToken snsAccessToken = getSnsToken(code);
		return snsAccessToken.getUser_id();
	}
	
	/**
	 * 拉取用户信息
	 * @param code 换取身份唯一凭证
	 * @return 网页授权用户对象
	 * @throws AlipayException
	 */
	public SnsUser getSnsUserByCode(String code) throws AlipayException {
		if (StringUtils.isEmpty(code)) {
            throw new IllegalArgumentException("code can't be null or empty");
        }
		SnsAccessToken accessToken = getSnsToken(code);
		return getSnsUser(accessToken.getAccess_token());
	}
	
	
	/**
	 * 通过授权码换取换取授权访问令牌
	 * @param authCode 回调回传的授权码
	 * @return 网页授权 SnsAccessToken
	 */
	public SnsAccessToken getSnsToken(String authCode) throws AlipayException {
		if (StringUtils.isEmpty(authCode)) {
            throw new IllegalArgumentException("code can't be null or empty");
        }
		Map<String, String> body = new HashMap<String, String>();
		body.put("grant_type", "authorization_code");
		body.put("code", authCode);
		body.put("method", "alipay.system.oauth.token");
		Response response = new AlipayHttpsClient(super.alipay).post(body);
		//根据请求结果判定，是否验证成功
		JSONObject bodyRes = getObjRes(response, "alipay_system_oauth_token_response");
    	if (Configuration.isDebug()) {
            System.out.println("getSnsOAuth2AccessToken返回json：" + bodyRes.toString());
        }
        String codeRes = bodyRes.getString("code");
        if (codeRes != null) {
        	String sub_code = bodyRes.getString("sub_code");
        	String sub_msg = bodyRes.getString("sub_msg");
            //返回异常信息
            throw new AlipayException(getCause(sub_code,sub_msg));
        }
        return new SnsAccessToken(bodyRes);
	}
	
	
	
	/**
	 * 根据授权的token获得用户信息
	 * @param access_token
	 * @return
	 */
	public SnsUser getSnsUser(String access_token) throws AlipayException {
		if (StringUtils.isEmpty(access_token)) {
            throw new IllegalArgumentException("access_token can't be null or empty");
        }
		SnsUser user = null;
		Map<String, String> body = new HashMap<String, String>();
		body.put("auth_token", access_token);
		Response res = new AlipayHttpsClient(super.alipay).post(body);
		//根据请求结果判定，是否验证成功
        JSONObject bodyRes = getObjRes(res, "alipay_user_info_share_response");
        if (Configuration.isDebug()) {
            System.out.println("getSnsUser返回json：" + bodyRes.toString());
        }
        String codeRes = bodyRes.getString("code");
        if (!"10000".equals(codeRes)) {
        	String sub_code = bodyRes.getString("sub_code");
        	String sub_msg = bodyRes.getString("sub_msg");
            //返回异常信息
            throw new AlipayException(getCause(sub_code,sub_msg));
        }
        //设置公众号信息
        user = JSONObject.toJavaObject(bodyRes, SnsUser.class);
		return user;
	}
	
}
